package com.real.fact.web.application;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;

import javax.sql.DataSource;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;
import net.sf.jasperreports.engine.xml.JRXmlLoader;

public abstract class GeneratePDFReportCommand extends FillOutputStreamCommand {

  protected abstract Map<String, Object> getParameters();

  protected abstract String getReportName();

  protected final DataSource dataSource;

  public GeneratePDFReportCommand(final DataSource theDataSource) {
    dataSource = theDataSource;
  }

  public Void execute() {
    Connection connection = null;
    try {
      InputStream is = getClass().getResourceAsStream("/reports/" + getReportName() +".jrxml");
      JasperDesign design = JRXmlLoader.load(is);
      customizeDesign(design);      
      JasperReport report = JasperCompileManager.compileReport(design);
      report.setWhenNoDataType(
          WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
      Map<String, Object> parameters = getParameters();
      connection = dataSource.getConnection();
      JasperPrint print = JasperFillManager.fillReport(report, parameters, connection);
      JasperExportManager.exportReportToPdfStream(print,
          outputStream);
    } catch (JRException e) {
      throw new RuntimeException (e);
    } catch (SQLException e) {
      throw new RuntimeException (e);
    } finally {
      // DbUtils has rollbackAndCloseQuietly(connection), not used here because
      // we would add another dependency.
      if (connection != null) {
        try {
          connection.rollback();
        } catch (SQLException e) {
        }
        try {
          connection.close();
        } catch (SQLException e) {
        }
      }
    }
    return null;
  }

  protected void customizeDesign(JasperDesign design) {
    
  }

}